package com.gcloud.controller.compute.workflow.vm.iso;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.gcloud.controller.compute.dao.InstanceDao;
import com.gcloud.controller.compute.entity.VmInstance;
import com.gcloud.controller.compute.service.vm.base.IVmBaseService;
import com.gcloud.controller.compute.service.vm.iso.IVmIsoService;
import com.gcloud.controller.compute.workflow.model.iso.DetachIsoInitFlowCommandReq;
import com.gcloud.controller.compute.workflow.model.iso.DetachIsoInitFlowCommandRes;
import com.gcloud.controller.image.dao.VmIsoAttachmentDao;
import com.gcloud.controller.image.entity.VmIsoAttachment;
import com.gcloud.core.workflow.core.BaseWorkFlowCommand;
import com.gcloud.header.compute.enums.Device;
import com.gcloud.header.compute.enums.StorageType;
import com.gcloud.header.compute.enums.VmIsoAttachStatus;
import com.gcloud.header.compute.msg.node.vm.model.VmCdromDetail;

import lombok.extern.slf4j.Slf4j;
/**
Copyright (c) [2020] [G-CLOUD TECHNOLOGY] [G-Cloud 8.0] is licensed under the Mulan PSL v1.
You can use this software according to the terms and conditions of the Mulan PSL v1. You may obtain
a copy of Mulan PSL v1 at: http://license.coscl.org.cn/MulanPSL THIS SOFTWARE IS PROVIDED ON AN 
"AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v1 for more details.
 */

@Component
@Scope("prototype")
@Slf4j
public class DetachIsoInitFlowCommand extends BaseWorkFlowCommand{

    @Autowired
    private InstanceDao instanceDao;

    @Autowired
    private IVmBaseService vmBaseService;

    @Autowired
    private IVmIsoService vmIsoService;
    
    @Autowired
    private VmIsoAttachmentDao isoAttachmentDao;
    
	@Override
	protected Object process() throws Exception {
		DetachIsoInitFlowCommandReq req = (DetachIsoInitFlowCommandReq) getReqParams();
        DetachIsoInitFlowCommandRes res = new DetachIsoInitFlowCommandRes();

        vmIsoService.detachIsoInit(req.getInstanceId(), req.getIsoId(), req.getInTask());

        try {
        	List<VmIsoAttachment> isoAttachments = isoAttachmentDao.findByIsoIdAndInstanceId(req.getIsoId(), req.getInstanceId());
            VmIsoAttachment attach = isoAttachments.get(0);
            attach.setStatus(VmIsoAttachStatus.DETACHING.name());
            
            isoAttachmentDao.update(attach);
            
            VmInstance instance = instanceDao.getById(req.getInstanceId());

            VmCdromDetail vmCdromDetail = vmIsoService.isoDetail(req.getIsoId(), req.getInstanceId());

            res.setInstanceId(req.getInstanceId());
            res.setIsoId(req.getIsoId());
            res.setHostname(instance.getHostname());
            res.setVmCdromDetail(vmCdromDetail);
            res.setTaskId(UUID.randomUUID().toString());
        } catch (Exception ex) {
            errorRollback();
            throw ex;
        }
        return res;
	}

	@Override
	protected Object rollback() throws Exception {
		errorRollback();
		return null;
	}
	
	private void errorRollback() {
        DetachIsoInitFlowCommandReq req = (DetachIsoInitFlowCommandReq) getReqParams();
        DetachIsoInitFlowCommandRes res = (DetachIsoInitFlowCommandRes) getReqParams();

        List<VmIsoAttachment> isoAttachments = isoAttachmentDao.findByIsoIdAndInstanceId(req.getIsoId(), req.getInstanceId());
        VmIsoAttachment attach = isoAttachments.get(0);
        if(attach != null) {
	        attach.setStatus(VmIsoAttachStatus.ATTACHED.name());
	        
	        isoAttachmentDao.update(attach);
        } else {
        	VmIsoAttachment vmIso = new VmIsoAttachment();
    		vmIso.setInstanceId(req.getInstanceId());
    		vmIso.setCreatedAt(new Date());
    		vmIso.setIsoId(req.getIsoId());
    		vmIso.setMountpoint(Device.HDC.getValue());
    		vmIso.setStatus(VmIsoAttachStatus.ATTACHED.name());
    		vmIso.setIsoPool(res.getVmCdromDetail().getIsoPool());
    		vmIso.setIsoPoolId(res.getVmCdromDetail().getIsoPoolId());
    		vmIso.setIsoStorageType(res.getVmCdromDetail().getIsoStorageType());
    		
    		isoAttachmentDao.save(vmIso);
        }

        vmBaseService.cleanState(req.getInstanceId(), req.getInTask());
    }

	@Override
	protected Object timeout() throws Exception {
		return null;
	}

	@Override
	protected Class<?> getReqParamClass() {
		return DetachIsoInitFlowCommandReq.class;
	}

	@Override
	protected Class<?> getResParamClass() {
		return DetachIsoInitFlowCommandRes.class;
	}

}